/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package dawnland03.service;

import dawnland03.data.map.algorithm.astar.MatrixOperations;
import dawnland03.data.map.model.Matrix;
import dawnland03.data.map.model.MatrixCell;
import dawnland03.data.map.service.MatrixOperationsImpl;
import dawnland03.data.map.service.MatrixService;
import dawnland03.model.entity.attribute.Position;
import dawnland03.model.entity.EntityFactory;
import dawnland03.model.entity.Entity;
import dawnland03.model.team.Team;
import dawnland03.model.team.TeamFactory;

import java.util.HashSet;
import java.util.Set;
import java.util.List;
import java.util.LinkedList;

/**
 * @author Petru Obreja (obrejap@yahoo.com)
 */
public class GeneralFacade {
    private static Matrix matrix;

    private static MatrixService matrixService;

    //def MATRIX_FILE_PATH = "{__DIR__}../resources/matrix.xml";
    private static final String MATRIX_FILE_PATH = "F:/work/javafx/dawnland/dawnland03/src/dawnland03/resources/matrix.xml "; //to be modified later, using a ConstantProperties class

    static {
        MatrixOperations matrixOperations = new MatrixOperationsImpl();
        matrixService = new MatrixService(matrixOperations);
    }

    public static Matrix getMatrix() {
        if (matrix == null) {
            matrix = matrixService.readMatrix(MATRIX_FILE_PATH);
        }
        return matrix;
    }

    public static List<MatrixCell> getClosestPath(Entity entity, Integer startMatrixCellId, Integer endMatrixCellId) {
        return getClosestPath(entity, getMatrix().getMatrixCell(startMatrixCellId), getMatrix().getMatrixCell(endMatrixCellId));
    }

    public static List<MatrixCell> getClosestPath(Entity entity, Integer startX, Integer startY, Integer endMatrixCellId) {
        MatrixCell endMatrixCell = getMatrix().getMatrixCell(endMatrixCellId);
        return matrixService.getClosestPath(entity, getMatrix(), startX, startY, endMatrixCell.getX(), endMatrixCell.getY());
    }

    public static List<Integer> getClosestPathAsIds(Entity entity, Integer startMatrixCellId, Integer endMatrixCellId) {
        List<MatrixCell> matrixCells = getClosestPath(entity, startMatrixCellId, endMatrixCellId);
        List<Integer> path = new LinkedList<Integer>();
        for (MatrixCell matrixCell : matrixCells) {
            path.add(matrixCell.getId());
        }
        return path;
    }

    public static List<MatrixCell> getClosestPath(Entity entity, MatrixCell start, MatrixCell end) {
        return matrixService.getClosestPath(entity, getMatrix(), start.getX(), start.getY(), end.getX(), end.getY());
    }

    public static boolean acquireLockOnEntityLayer(Integer entityId, Integer matrixCellId, Long timeout) {
        return matrix.getEntityMatrixCellLayer(matrixCellId).tryAcquire(entityId, timeout);
    }

    public static void releaseLockOnEntityLayer(Integer entityId, Integer matrixCellId) {
        matrix.getEntityMatrixCellLayer(matrixCellId).releaseLockOnEntityLayer(entityId);
    }

    public static void testThreads() {
        Integer initialNumberOfTeamMembers = 8;
        Team team = TeamFactory.createTeam("teamOne", initialNumberOfTeamMembers);
        Set<Position> positions = new HashSet<Position>();
        for (int i = 0; i < initialNumberOfTeamMembers; i++) {
            positions.add(new Position(i, i));
        }
        EntityFactory.createGroupOfEntities(team, positions);
    }
}
